﻿Option Strict On
''' <summary>
''' This class is use to read data from a Metaquery, it also represent the Command Screen
''' So we can access easily the informations
''' Ex. Metaqueries, MetaColumns...
''' </summary>
''' <remarks></remarks>
<Serializable()>
Public Class MetaQuery
    Implements IDisposable
#Region " FIELD "
    Private _sqlStatement As String
    Private _recordVersionField As String
    Private _metaColumns As DataTable = New DataTable()
    Private _metaParams As DataTable = New DataTable()

    Private _childQueries As List(Of MetaQuery) = New List(Of MetaQuery)
    Private _metaColumnCaption As Dictionary(Of String, String) = New Dictionary(Of String, String)

    Private metaCUDCommand As MetaQuery = Nothing

    Private _listOfLov As Dictionary(Of String, Guid) = New Dictionary(Of String, Guid)
    Private _listOfLookup As Dictionary(Of String, Guid) = New Dictionary(Of String, Guid)

    Private _listOfVisibleLov As Dictionary(Of String, Guid) = New Dictionary(Of String, Guid)
    Private _listOfVisibleLookup As Dictionary(Of String, Guid) = New Dictionary(Of String, Guid)

#End Region

#Region " Events "

    Public Event BeforeSql(ByVal mq As MetaQuery, ByVal e As System.ComponentModel.CancelEventArgs)
    'Public Event OnBeforeSQL As System.ComponentModel.CancelEventHandler
#End Region

#Region " Property "
    Public Property MetaQuerieCD As String
    Public Property MetaControlID As Guid = Nothing 'André aime pas ça quand y a pas de valeur , BD
    Public Property AllowCreate() As Boolean = True 'set to true to continue all Possiblity with Preview MetaCommand , BD
    Public Property AllowRead() As Boolean = True    'set to true to continue all Possiblity with Preview MetaCommand ,BD
    Public Property AllowUpdate() As Boolean = True   'set to true to continue all Possiblity with Preview MetaCommand ,BD
    Public Property AllowDelete() As Boolean = True   'set to true to continue all Possiblity with Preview MetaCommand ,BD
    Public Property ApplicationName() As String
    Public Property Caption() As String               'André dit que par Default STRING c'est empty , mais ça l'évarve , BD
    Public Property CaptionId() As Guid = Nothing
    Public Property CommandCategoryID() As Guid = Nothing
    Public Property CommandClassID() As Guid = Nothing
    Public Property CommandGroupID() As Guid = Nothing
    Public Property CommandTypeID() As Guid = Nothing
    Public Property DefaultParentValue() As Dictionary(Of String, Object) = New Dictionary(Of String, Object)()
    Public Property ParentID() As Guid = Nothing
    Public Property QueryID() As Guid
    Public Property RelationOrder() As Integer
    Public Property PKColumn_Name As String
    Public Property FKColumn_Name As String
    Public Property TipId() As Guid = Nothing
    Public Property GUIDField() As String
    Public Property QueryName() As String
    Public Property SQLFrom() As String
    Public Property SQLGroupBy() As String
    Public Property SQLHaving() As String
    Public Property SQLOrderBy() As String
    Public Property SQLSelect() As String
    Public Property ResultQuery() As DataTable = Nothing
    Public Property SQLWhere() As String
    Public Property SQLWhereContext() As String
    Public Property ToolTip() As String
    Public Property UniqueTable() As String

    ''' <summary>
    ''' Shortcut to test if we have Lookup to proceed by the consumer (Ex.: ExtendedGrid)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property HasLookup() As Boolean
        Get
            Return _listOfLookup.Count > 0
        End Get
    End Property
    ''' <summary>
    ''' Shortcut to test if we have LOV to proceed by the consumer (Ex.: ExtendedGrid)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property HasLov() As Boolean
        Get
            Return _listOfLov.Count() > 0
        End Get
    End Property
    ''' <summary>
    ''' Lookup list that will be process by the main consumer
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ListOfLookup() As Dictionary(Of String, Guid)
        Get
            Return _listOfLookup
        End Get
    End Property
    ''' <summary>
    ''' Lookup list that will be process by the main consumer
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ListOfVisibleLookup() As Dictionary(Of String, Guid)
        Get
            Return _listOfVisibleLookup
        End Get
    End Property

    ''' <summary>
    ''' LOV list that will be process by the main consumer
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ListOfLov() As Dictionary(Of String, Guid)
        Get
            Return _listOfLov
        End Get
    End Property
    ''' <summary>
    ''' LOV list that will be process by the main consumer
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ListOfVisibleLov() As Dictionary(Of String, Guid)
        Get
            Return _listOfVisibleLov
        End Get
    End Property

    ''' <summary>
    ''' Collection of child Query
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property ChildQueries() As List(Of MetaQuery)
        Get
            If _childQueries.Count = 0 Then
                Me.FillChildQuery()
            End If
            Return _childQueries
        End Get
        Set(ByVal value As List(Of MetaQuery))
            _childQueries = value
        End Set
    End Property
    Public ReadOnly Property MetaColumnCaption() As Dictionary(Of String, String)
        Get
            Return _metaColumnCaption
        End Get
    End Property
    ''' <summary>
    ''' All the column from the select statement
    ''' 
    ''' By design we initialise the metacolumns if it's not fill. MetaDataTable access this property.
    ''' For backward compatibility we automaticly Fill it.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>For caching purpose we can assign the property</remarks>
    Public Property MetaColumns() As DataTable
        Get
            If _metaColumns.Rows.Count = 0 Then
                FillMetaColumns()
            End If
            Return _metaColumns
        End Get
        Set(value As DataTable)
            _metaColumns = value
        End Set
    End Property

    Public Property MetaParams() As DataTable
        Get
            If _metaParams.Rows.Count = 0 Then
                FillMetaParams()
            End If
            Return _metaParams
        End Get
        Set(value As DataTable)
            _metaParams = value
        End Set
    End Property
    ''' <summary>
    ''' Witch field to be use for Version, default = TStamp
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>TODO: Remove when all table will be base on RecordVersion, not TStamp </remarks>
    Public Property RecordVersionField() As String
        Get
            If String.IsNullOrEmpty(_recordVersionField) Then
                If Me.SQLStatement.Contains("RecordVersion") Then
                    _recordVersionField = "RecordVersion"
                Else
                    _recordVersionField = "TStamp"
                End If
            End If
            Return _recordVersionField
        End Get
        Set(ByVal value As String)
            _recordVersionField = value
        End Set
    End Property

    ''' <summary>
    ''' Contain the result of the SQLStatement
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>For caching purpose we can assign the property</remarks>

    Public Property SQLStatement() As String
        Get
            If String.IsNullOrEmpty(_sqlStatement) Then
                With New Text.StringBuilder
                    If Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT Then
                        .Append("SELECT ")
                    End If

                    .Append(Me.SQLSelect)

                    If Me.SQLFrom <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("FROM ")
                        .Append(Me.SQLFrom)
                    End If

                    If Me.SQLWhere <> String.Empty Or Me.SQLWhereContext <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("WHERE ")
                        .Append(Me.SQLWhere)

                        'Extra condition to apply from a specific context. ex.: parameter set from a form
                        'An other WHERE from another MetaCommand
                        If Me.SQLWhereContext <> String.Empty Then
                            If .Length > 0 Then .Append(" ")
                            If Me.SQLWhere <> String.Empty Then .Append(" AND ")
                            .Append(Me.SQLWhereContext)
                        End If
                    End If

                    If Me.SQLGroupBy <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("GROUP BY ")
                        .Append(Me.SQLGroupBy)
                    End If

                    If Me.SQLHaving <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("HAVING ")
                        .Append(Me.SQLHaving)
                    End If
                    If Me.SQLOrderBy <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("ORDER BY ")
                        .Append(Me.SQLOrderBy)
                    End If
                    _sqlStatement = .ToString
                End With
            End If
            Return _sqlStatement
        End Get
        Set(ByVal value As String)
            _sqlStatement = value
        End Set
    End Property

    ''' <summary>
    ''' Return a SQL Statement, that can be use in a Sub Select. 
    ''' Created for PLBase so we can have Where clause also propagate to child Query
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property SQLStatementParsed() As String
        Get
            If String.IsNullOrEmpty(_sqlStatement) Then
                With New Text.StringBuilder
                    If Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT Then
                        .Append("SELECT " & vbCrLf)
                    End If

                    .Append(Me.SQLSelect & vbCrLf)

                    If Me.SQLFrom <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("FROM " & vbCrLf)
                        .Append(Me.SQLFrom & vbCrLf)
                    End If

                    If Me.SQLWhere <> String.Empty Or Me.SQLWhereContext <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("WHERE " & vbCrLf)
                        .Append(Me.SQLWhere & vbCrLf)

                        'Extra condition to apply from a specific context. ex.: parameter set from a form
                        'An other WHERE from another MetaCommand
                        If Me.SQLWhereContext <> String.Empty Then
                            If .Length > 0 Then .Append(" ")
                            If Me.SQLWhere <> String.Empty Then .Append(" AND ")
                            .Append(Me.SQLWhereContext & vbCrLf)
                        End If
                    End If

                    If Me.SQLGroupBy <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("GROUP BY " & vbCrLf)
                        .Append(Me.SQLGroupBy & vbCrLf)
                    End If

                    If Me.SQLHaving <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("HAVING " & vbCrLf)
                        .Append(Me.SQLHaving & vbCrLf)
                    End If
                    If Me.SQLOrderBy <> String.Empty Then
                        If .Length > 0 Then .Append(" ")
                        .Append("ORDER BY " & vbCrLf)
                        .Append(Me.SQLOrderBy & vbCrLf)
                    End If
                    _sqlStatement = .ToString
                End With
            End If
            Return _sqlStatement
        End Get
        Set(ByVal value As String)
            _sqlStatement = value
        End Set
    End Property


#End Region

#Region " Methode "

    Public Function GetSQLForSubSelect(ByVal fields As String) As String
        Dim sql As String

        With New Text.StringBuilder
            If Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT Then
                .Append("SELECT " & vbCrLf)
            End If

            .Append(fields & vbCrLf)

            If Me.SQLFrom <> String.Empty Then
                If .Length > 0 Then .Append(" ")
                .Append("FROM " & vbCrLf)
                .Append(Me.SQLFrom & vbCrLf)
            End If

            If Me.SQLWhere <> String.Empty Or Me.SQLWhereContext <> String.Empty Then
                If .Length > 0 Then .Append(" ")
                .Append("WHERE " & vbCrLf)
                .Append(Me.SQLWhere & vbCrLf)

                'Extra condition to apply from a specific context. ex.: parameter set from a form
                'An other WHERE from another MetaCommand
                If Me.SQLWhereContext <> String.Empty Then
                    If .Length > 0 Then .Append(" ")
                    If Me.SQLWhere <> String.Empty Then .Append(" AND ")
                    .Append(Me.SQLWhereContext & vbCrLf)
                End If
            End If

            If Me.SQLGroupBy <> String.Empty Then
                If .Length > 0 Then .Append(" ")
                .Append("GROUP BY " & vbCrLf)
                .Append(Me.SQLGroupBy & vbCrLf)
            End If

            If Me.SQLHaving <> String.Empty Then
                If .Length > 0 Then .Append(" ")
                .Append("HAVING " & vbCrLf)
                .Append(Me.SQLHaving & vbCrLf)
            End If
            sql = .ToString
        End With
        Return sql
    End Function



    Public Sub New()
        ResultQuery = New DataTable()
    End Sub


    ''' <summary>
    '''  Return a DataTable with Schema info of the SQL Statement
    ''' </summary>
    ''' <remarks>Call from Generate Columns (Value) </remarks>
    Public Function GetSQLSchemaInfo() As DataTable
        Dim command As SqlCommand = Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Dim dataTbl As DataTable = Nothing
        Dim tmpWhere As String
        Try

            tmpWhere = Me.SQLWhere
            Me.SQLWhere = String.Empty
            _sqlStatement = Nothing
            command.CommandText = Me.SQLStatement
            Me.SQLWhere = tmpWhere
            _sqlStatement = Nothing
            '
            If Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SP Then
                command.CommandType = CommandType.StoredProcedure
            End If
            'Pour des raison de performance on demande le CommandBehavior.SchemaOnly.
            'BUGBUG: Si une SP a plusieurs commande ca ne fonctionne pas. il faut faire le ExecuteReader seulement.
            reader = command.ExecuteReader(CommandBehavior.SchemaOnly)
            'reader = command.ExecuteReader()
            dataTbl = reader.GetSchemaTable()
            Return dataTbl
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.GetSchemaInfo()(){0}{1}{0}{0}Queryname: {2}", vbCrLf, Me.SQLStatement, Me.QueryName))
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            If command.Connection.State = ConnectionState.Open Then
                command.Connection.Close()
                command.Connection.Dispose()
            End If
            command.Dispose()
            command = Nothing
        End Try
    End Function
    ''' <summary>
    '''  Return a DataTable with Schema info of the SQL Parameters of the SP
    ''' </summary>
    ''' <remarks></remarks>
    Public Function GetSPSchemaInfo() As DataTable
        Dim dataTbl As DataTable = Nothing
        Dim dataRow As DataRow = Nothing

        Using sqlcommand As SqlCommand = MetaQuery.GetSPCmdByMetaName(Me.QueryName)
            If sqlcommand IsNot Nothing Then
                dataTbl = New DataTable("SchemaTable")
                dataTbl.Columns.Add("ColumnName")
                dataTbl.Columns.Add("DataTypeName")
                dataTbl.Columns.Add("DataType")
                For Each param As SqlParameter In sqlcommand.Parameters
                    dataRow = dataTbl.NewRow()
                    dataRow("ColumnName") = param.ParameterName
                    dataRow("DataTypeName") = param.SqlDbType.ToString
                    dataRow("DataType") = Base.IdRepository.SqlDbTypeToType(param.SqlDbType).ToString
                    dataTbl.Rows.Add(dataRow)
                Next
            End If
        End Using
        Return dataTbl
    End Function

    Public Function InitQueryParams() As SqlCommand
        Dim sqlcmd As SqlCommand = Base.Connection.Command
        sqlcmd.CommandText = Me.SQLStatement
        If Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SP Then
            sqlcmd.CommandType = CommandType.StoredProcedure
        End If

        Dim param As SqlParameter
        For Each row As DataRow In Me.MetaParams.Rows
            param = New SqlParameter(row("ColumnName").ToString, Base.IdRepository.GUIDToSqlDbType(CType(row("pDataTypeID_FK"), Guid)))
            sqlcmd.Parameters.Add(param)
        Next
        Return sqlcmd
    End Function
    ''' <summary>
    '''  Fill a DataTable from the query
    ''' </summary>
    ''' <param name="CommandBehavior"></param>
    ''' <param name="sqlCmd"> Use to execute an SP With Parameters already set by the caller (Ex: ReportBuilder or Pivot Table)</param>
    ''' <remarks></remarks>
    ''' 
    Public Sub FillResultQuery(Optional ByVal CommandBehavior As CommandBehavior = CommandBehavior.Default, Optional sqlCmd As SqlCommand = Nothing)
        Dim command As SqlCommand = Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Try
            Me.ResultQuery.Clear()
            Me.ResultQuery.TableName = Me.QueryName
            OnBeforeSql(Me)
            '
            If Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SP Then
                If sqlCmd IsNot Nothing Then
                    command = sqlCmd.Clone()
                    sqlCmd.Dispose()
                End If
                command.CommandType = CommandType.StoredProcedure
            End If
            command.CommandText = Me.SQLStatement
            reader = command.ExecuteReader(CommandBehavior)
            '
            'begin load does not validate all the integrity of the table. (help for speed)
            'it's ok here cause we are loading from the DB.
            Me.ResultQuery.BeginLoadData()
            Me.ResultQuery.Load(reader)
            Me.ResultQuery.EndLoadData()
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.FillResultQuery(){0}{1}{0}{0}Queryname: {2}", vbCrLf, Me.SQLStatement, Me.QueryName), ex)
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            If command.Connection.State = ConnectionState.Open Then
                command.Connection.Close()
                command.Connection.Dispose()
            End If
            command.Dispose()
            command = Nothing
        End Try
    End Sub
    ''' <summary>
    ''' Use when you need to call a specific UPDATE/DELETE or INSERT statement
    ''' Use the ExecuteNonQuery of the SqlCommand
    ''' </summary>
    ''' <remarks></remarks>
    Public Function ExecuteQuery() As Integer
        Dim command As SqlCommand = Base.Connection.Command
        Try
            command.CommandText = Me.SQLStatement
            Return command.ExecuteNonQuery()
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.ExecuteQuery(){0}{1}{0}{0}Queryname: {2}", vbCrLf, Me.SQLStatement, Me.QueryName))
        Finally
            command.Connection.Close()
            command.Connection.Dispose()
            command.Dispose()
            command = Nothing
        End Try
    End Function




    ''' <summary>
    ''' Give the possibility to modify the Metaquery before the SQL is executed
    ''' </summary>
    ''' <param name="mq"></param>
    ''' <remarks></remarks>
    Public Sub OnBeforeSql(ByVal mq As MetaQuery)
        Dim e As New System.ComponentModel.CancelEventArgs(False)
        RaiseEvent BeforeSql(mq, e)
        If Not e.Cancel Then
            Me.CopyTo(mq)
        End If
    End Sub
    ''' <summary>
    ''' Copy the properties of the current instance to the one pass in parameter
    ''' </summary>
    ''' <param name="mq">MetaQuery that receive the properties</param>
    ''' <remarks></remarks>
    Public Sub CopyTo(ByVal mq As MetaQuery)
        mq.QueryID = Me.QueryID
        mq.ApplicationName = Me.ApplicationName
        mq.QueryName = Me.QueryName
        mq.ParentID = Me.ParentID
        mq.UniqueTable = Me.UniqueTable
        mq.GUIDField = Me.GUIDField
        '
        mq.CommandCategoryID = Me.CommandCategoryID
        mq.CommandClassID = Me.CommandClassID
        mq.CommandGroupID = Me.CommandGroupID
        mq.CommandTypeID = Me.CommandTypeID
        '
        mq.SQLSelect = Me.SQLSelect
        mq.SQLFrom = Me.SQLFrom
        mq.SQLWhere = Me.SQLWhere
        mq.SQLWhereContext = Me.SQLWhereContext
        mq.SQLOrderBy = Me.SQLOrderBy
        mq.SQLGroupBy = Me.SQLGroupBy
        mq.SQLHaving = Me.SQLHaving

        mq.RelationOrder = Me.RelationOrder
        mq.PKColumn_Name = Me.PKColumn_Name
        mq.FKColumn_Name = Me.FKColumn_Name
        mq.CaptionId = Me.CaptionId
        mq.TipId = Me.TipId
        mq.Caption = Me.Caption
        mq.ToolTip = Me.ToolTip
        mq.MetaQuerieCD = Me.MetaQuerieCD
        mq.MetaControlID = Me.MetaControlID
        mq.AllowCreate = Me.AllowCreate
        mq.AllowRead = Me.AllowRead
        mq.AllowUpdate = Me.AllowUpdate

    End Sub
#End Region

#Region " Function "
    Public Shared Function GetDataById(ByVal queryName As String, ByVal id As Guid) As DataRow
        Dim aRow As DataRow = Nothing
        Using aMq As MetaQuery = MetaQuery.GetMetaQueryByName(queryName)
            aMq.SQLWhere = String.Format("{0} = '{1}'", aMq.GUIDField, id.ToString)
            aMq.FillResultQuery()
            If aMq.ResultQuery.Rows.Count > 0 Then
                aRow = aMq.ResultQuery.Rows(0)
            End If
            Return aRow
        End Using
    End Function
    ''' <summary>
    ''' Build a Store Proc SQLCommand Base On a MetaQuery - Make Sure Your StoreProc Parameters Match The Column Name Of Your Tables
    ''' </summary>
    ''' <param name="queryName"></param>
    ''' <param name="applicationName"></param>
    ''' <returns></returns>
    ''' <remarks>Make Sure Your StoreProc Parameters Match The Column Name Of Your Tables</remarks>
    Public Shared Function GetSPCmdByMetaName(ByVal queryName As String, Optional ByVal applicationName As String = Nothing) As SqlCommand
        Dim mq As MetaQuery
        mq = MetaQuery.GetMetaQueryByName(queryName, applicationName)
        If mq Is Nothing Then
            Throw New Exception(String.Format("Invalid MetaCommand: MetaQuery.GetSPCmdByName(){0}{1}", vbCrLf, queryName))
        End If
        Return MetaQuery.GetSPCmdByMeta(mq)
    End Function

    ''' <summary>
    ''' Build a Store Proc SQLCommand Base On a MetaQuery ID - Make Sure Your StoreProc Parameters Match The Column Name Of Your Tables
    ''' </summary>
    ''' <param name="queryID"></param>
    ''' <param name="applicationName"></param>
    ''' <returns></returns>
    ''' <remarks>Make Sure Your StoreProc Parameters Match The Column Name Of Your Tables</remarks>
    Public Shared Function GetSPCmdByMetaID(ByVal queryID As System.Guid, Optional ByVal applicationName As String = Nothing) As SqlCommand
        Dim mq As MetaQuery
        mq = MetaQuery.GetMetaQueryById(queryID)
        If mq Is Nothing Then
            Throw New Exception(String.Format("Invalid MetaCommand: MetaQuery.GetSPCmdByID(){0}{1}", vbCrLf, queryID))
        End If
        Return MetaQuery.GetSPCmdByMeta(mq)
    End Function



    Private Shared Function GetSSPMetaQuery(Optional ByVal queryId As Guid = Nothing, Optional ByVal queryName As String = "", Optional ByVal applicationName As String = Nothing) As MetaQuery
        Dim mq As MetaQuery
        Dim command As System.Data.SqlClient.SqlCommand = CommonExt.Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Try
            command.CommandText = "ssp_MetaQuery"
            command.CommandType = CommandType.StoredProcedure

            command.Parameters.AddWithValue("@QueryID", queryId)
            command.Parameters.AddWithValue("@QueryName", queryName)
            command.Parameters.AddWithValue("@ApplicationName", applicationName)

            'Ne pas utiliser Base.AppManager.ApplicationOption.LanguageId ca creer une boucle infinie, 
            'GetSSPMetaQuery est la fonction du framework SCIEF la plus appeler, 
            'ApplicationOption en a besoin pour déterminer le language de l'usager
            'command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.ApplicationOption.LanguageId)
            '
            command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.LanguageId)
            '
            reader = command.ExecuteReader(CommandBehavior.CloseConnection)
            mq = GetMetaQueryProperties(reader)
            Return mq
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            command.Dispose()
            command = Nothing
        End Try
    End Function

    Public Shared Function GetMetaQueryByControlID(ByVal controlID As Guid) As MetaQuery
        Dim mq As MetaQuery
        Dim command As System.Data.SqlClient.SqlCommand = CommonExt.Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Try
            command.CommandText = "ssp_MetaQueryByControlID"
            command.CommandType = CommandType.StoredProcedure

            command.Parameters.AddWithValue("@ControlID", controlID)
            command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.LanguageId)
            '
            reader = command.ExecuteReader(CommandBehavior.CloseConnection)
            mq = GetMetaQueryProperties(reader)
            Return mq
        Catch ex As Exception
            Throw
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            command.Dispose()
            command = Nothing
        End Try
    End Function
    ''' <summary>
    ''' Build an SQLCommand for StoredProc. and prepare the parameters
    ''' </summary>
    ''' <param name="mq">MetaQuery</param>
    ''' <param name="trimAt">When you need your SqlParameter.SourceColumn with no @ </param>
    ''' <returns>SqlCommand</returns>
    ''' <remarks>Convention a suivre. Parametername = Colonne</remarks>
    Public Shared Function GetSPCmdByMeta(ByVal mq As MetaQuery, Optional trimAt As Boolean = True) As SqlCommand
        'J'ai mis les constanats ici pour pouvoir garder ma Fonction Shared. aleblanc
        'Const METALIST_METACOMMANDTYPE_SP As String = "{8A6E0E00-F8C6-4B23-B75D-D4352242DC43}"
        'Dim valueSP = New Guid(METALIST_METACOMMANDTYPE_SP)
        '
        Dim command As SqlCommand = Nothing
        If mq.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SP Then
            command = Base.Connection.Command
            command.CommandText = mq.SQLSelect 'C'est une SP pas besoin de passer par mq.SQLStatement
            command.CommandType = CommandType.StoredProcedure
            'On va chercher les paramêtres de la SP 
            SqlCommandBuilder.DeriveParameters(command)

            'We check trimAt first, so we dont evaluate in each iteration of the For Each.
            If trimAt = True Then
                For Each param As SqlParameter In command.Parameters
                    'Convention a suivre. Parametername = Colonne
                    param.SourceColumn = param.ParameterName.TrimStart("@"c)
                    param.SourceVersion = DataRowVersion.Current
                Next
            Else
                For Each param As SqlParameter In command.Parameters
                    'Convention a suivre. Parametername = Colonne
                    param.SourceColumn = param.ParameterName
                    param.SourceVersion = DataRowVersion.Current
                Next
            End If

        Else
            Throw New Exception(String.Format("Not Define has SP: MetaQuery.GetSPCmdByName(){0}{1}", vbCrLf, mq.QueryName))
        End If
        Return command
    End Function

    ''' <summary>
    ''' Get the MetaCommand by Guid
    ''' </summary>
    ''' <param name="guid"></param>
    ''' <returns>Return Nothing when query is not found</returns>
    ''' <remarks>Guid are unique by definition, no need to pass the application name</remarks>
    Public Shared Function GetMetaQueryById(ByVal guid As Guid) As MetaQuery
        Return MetaQuery.GetSSPMetaQuery(guid)
    End Function
    ''' <summary>
    ''' Get the MetaCommand by Name
    ''' </summary>
    ''' <param name="queryName"></param>
    ''' <param name="applicationName"></param>
    ''' <returns>Return Nothing when query is not found</returns>
    ''' <remarks></remarks>
    Public Shared Function GetMetaQueryByName(ByVal queryName As String, Optional ByVal applicationName As String = Nothing) As MetaQuery
        Return MetaQuery.GetSSPMetaQuery(Nothing, queryName, applicationName)
    End Function

    Public Shared Function GetMetaQueryProperties(reader As SqlDataReader) As MetaQuery
        Dim query As MetaQuery = New MetaQuery

        If reader.Read() Then
            'Pk always there
            query.QueryID = New Guid(reader("QueryID").ToString)
            '
            query.ApplicationName = reader("ApplicationName").ToString
            query.GUIDField = reader("GUIDField").ToString
            query.QueryName = reader("QueryName").ToString
            query.SQLFrom = reader("SQLFrom").ToString
            query.SQLGroupBy = reader("SQLGroupBy").ToString
            query.SQLHaving = reader("SQLHaving").ToString
            query.SQLOrderBy = reader("SQLOrderBy").ToString
            query.SQLSelect = reader("SQLSelect").ToString
            query.SQLWhere = reader("SQLWhere").ToString
            query.UniqueTable = reader("UniqueTable").ToString
            'null allow
            If Not (IsDBNull(reader("CommandTypeID_FK"))) Then
                query.CommandTypeID = New Guid(reader("CommandTypeID_FK").ToString)
            End If
            If Not (IsDBNull(reader("CommandCategoryID_FK"))) Then
                query.CommandCategoryID = New Guid(reader("CommandCategoryID_FK").ToString)
            End If
            If Not (IsDBNull(reader("CommandClassID_FK"))) Then
                query.CommandClassID = New Guid(reader("CommandClassID_FK").ToString)
            End If
            If Not (IsDBNull(reader("CommandGroupID_FK"))) Then
                query.CommandGroupID = New Guid(reader("CommandGroupID_FK").ToString)
            End If
            If Not (IsDBNull(reader("ParentID_FK"))) Then
                query.ParentID = New Guid(reader("ParentID_FK").ToString)
            End If

            If Not (IsDBNull(reader("CaptionId_FK"))) Then
                query.CaptionId = New Guid(reader("CaptionId_FK").ToString)
            End If
            If Not (IsDBNull(reader("TipId_FK"))) Then
                query.TipId = New Guid(reader("TipId_FK").ToString)
            End If
            If Not (IsDBNull(reader("RelationOrder"))) Then
                query.RelationOrder = CInt(reader("RelationOrder"))
            End If
            query.PKColumn_Name = reader("PKColumn_Name").ToString
            query.FKColumn_Name = reader("FKColumn_Name").ToString
            query.MetaQuerieCD = reader("MetaQuerieCD").ToString
            query.AllowCreate = CBool(reader("AllowCreate"))
            query.AllowRead = CBool(reader("AllowRead"))
            query.AllowUpdate = CBool(reader("AllowUpdate"))
            query.ToolTip = reader("pToolTip").ToString
            query.Caption = reader("pCaption").ToString

        Else
            query = Nothing
        End If
        Return query
    End Function
    ''' <summary>
    ''' Go get the DataRow from a query base on the parameter.
    ''' SELECT * FROM "tableName" WHERE "guidFieldName" = "id"
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="guidFieldName"></param>
    ''' <param name="id"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function FetchRow(ByVal tableName As String, ByVal guidFieldName As String, ByVal id As Guid) As DataRow
        Dim command As SqlCommand = Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Dim dtrow As DataTable = New DataTable
        Dim dr As DataRow = Nothing
        Try
            command.CommandText = String.Format("SELECT * FROM {0} WHERE {1} = '{2}'", tableName, guidFieldName, id.ToString)
            reader = command.ExecuteReader(CommandBehavior.CloseConnection)
            If reader.HasRows Then
                dtrow.Load(reader)
                dr = dtrow.Rows(0)
            End If
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.FetchRow{0} {1}", vbCrLf, command.CommandText))
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            dtrow.Dispose()
            command.Dispose()
            dtrow = Nothing
            command = Nothing
        End Try
        Return dr
    End Function
    '
    Public Function RefetchRow(ByVal id As Guid) As DataRow
        Dim command As SqlCommand = Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Dim dtrow As DataTable = New DataTable
        Dim dr As DataRow = Nothing
        Try
            command.CommandText = Me.SQLRefetchRow(id)
            reader = command.ExecuteReader(CommandBehavior.CloseConnection)
            If reader.HasRows Then
                dtrow.Load(reader)
                dr = dtrow.Rows(0)
            End If
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.RefetchDataRow{0}{1}", vbCrLf, command.CommandText))
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            command.Dispose()
            command = Nothing
            dtrow.Dispose()
            dtrow = Nothing
        End Try
        Return dr
    End Function
    ''' <summary>
    '''  Refetch the RowVersion
    ''' </summary>
    ''' <param name="id"></param>
    ''' <returns></returns>
    ''' <remarks>Base on the function SQLRefetchRowVersion</remarks>
    Public Function RefetchRowVersion(ByVal id As Guid) As Byte()
        Dim command As SqlCommand = Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Dim recordVersion() As Byte = Nothing
        Try
            command.CommandText = Me.SQLRefetchRowVersion(id)
            reader = command.ExecuteReader(CommandBehavior.CloseConnection)
            If reader.Read() Then
                If Not (IsDBNull(reader(Me.RecordVersionField))) Then
                    recordVersion = CType(reader(Me.RecordVersionField), Byte())
                End If
            End If
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.RefetchRowVersion{0}{1}", vbCrLf, command.CommandText))
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            command.Dispose()
            command = Nothing
        End Try
        Return recordVersion
    End Function
    ''' <summary>
    ''' Go Get the MetaQuery for CUD
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>Base on ParentId and Classe = CUD </remarks>
    Public Function GetMetaCUDCommand() As MetaQuery
        Dim sqlcmd As SqlCommand = Nothing
        Dim mq As MetaQuery
        Dim reader As SqlDataReader = Nothing
        Try
            sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaQuery")
            sqlcmd.Parameters("@ParentID_FK").Value = Me.QueryID
            sqlcmd.Parameters("@CommandClassID_FK").Value = Base.IdRepository.METALIST_METACOMMANDCLASS_CUD
            reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection)
            mq = GetMetaQueryProperties(reader)
            Return mq
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            sqlcmd.Dispose()
            sqlcmd = Nothing
        End Try
    End Function
    ''' <summary>
    ''' SQL query to return the row version
    ''' </summary>
    ''' <param name="id"></param>
    ''' <returns></returns>
    ''' <remarks>The ID is the one define in the GUIDField, make sure it's guid field</remarks>
    Private Function SQLRefetchRowVersion(ByVal id As Guid) As String
        Return String.Format("SELECT {0} FROM {1} WHERE {2} = '{3}'", Me.RecordVersionField, Me.UniqueTable, Me.GUIDField, id.ToString)
    End Function
    ''' <summary>
    ''' SQL query to return the row 
    ''' </summary>
    ''' <param name="id"></param>
    ''' <returns></returns>
    ''' <remarks>The ID is the one define in the GUIDField, make sure it's guid field</remarks>
    Private Function SQLRefetchRow(ByVal id As Guid) As String
        With New Text.StringBuilder
            If Not Me.CommandTypeID = Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT Then
                .Append("SELECT ")
            End If
            .Append(Me.SQLSelect)
            If Me.SQLFrom <> String.Empty Then
                If .Length > 0 Then .Append(" ")
                .Append("FROM ")
                .Append(Me.SQLFrom)
            End If
            If .Length > 0 Then .Append(" ")
            .Append("WHERE ")
            If Me.SQLWhere <> String.Empty Then
                .Append(Me.SQLWhere)
                .Append(" AND ")
            End If
            .Append(String.Format("{0}.{1} = '{{{2}}}'", Me.UniqueTable, Me.GUIDField, id))
            Return .ToString
        End With
    End Function
    ''' <summary>
    ''' Va chercher les requêtes enfants pour le CUD.
    ''' La Metalist Classe, les MetaListValues.ListOrder doivent etre 0=Read et 1=CUD
    ''' Les autres ordre sont moint important....
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub FillChildQuery()

        Dim childQueriesDtb As DataTable = New DataTable()
        Dim mq As MetaQuery = New MetaQuery()
        Dim sqlcmd As System.Data.SqlClient.SqlCommand = Nothing
        Dim reader As SqlDataReader = Nothing
        Try
            sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaQueryChild")
            sqlcmd.Parameters("@QueryID").Value = Me.QueryID
            reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection)
            childQueriesDtb.BeginLoadData()
            childQueriesDtb.Load(reader)
            childQueriesDtb.EndLoadData()
            'Load The Collection
            For Each dr As DataRow In childQueriesDtb.Rows
                mq = MetaQuery.GetMetaQueryById(CType(dr("QueryID"), Guid))
                Me._childQueries.Add(mq)
            Next
        Catch ex As Exception
            Throw New Exception(String.Format("Invalid SQL command: MetaQuery.FillChildQuery(){0}{1}", vbCrLf, Me.SQLStatement))
        Finally
            If reader IsNot Nothing Then
                reader.Close()
                reader = Nothing
            End If
            If sqlcmd IsNot Nothing Then
                sqlcmd.Dispose()
                sqlcmd = Nothing
            End If
            mq.Dispose()
            childQueriesDtb.Dispose()
        End Try
    End Sub
    ''' <summary>
    ''' Ici on va chercher toute les requetes d'affichage pour batir le DataSet
    ''' (Toute les requêtes, enfants)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>Retourne le DataTable avec les champs suivants: 
    ''' (0)	{MetaqueryLevel}	
    ''' (1)	{ParentRelation}	
    ''' (2)	{Relation}	
    ''' (3)	{ParentQueryName}	
    ''' (4)	{CommandCategory}
    ''' (5)	{QuerieCD}
    ''' (6)	{QueryName}
    ''' (7)	{PKColumn_Name}	
    ''' (8)	{FKColumn_Name}	
    ''' (9)	{ParentId_FK}	
    ''' (10)	{ParentGUIDField}	
    ''' (11)	{GUIDField}	
    ''' (12)	{RelationOrder}	
    ''' (13)	{ControlID_FK}	
    ''' </remarks>
    Public Function GetChildDisplayQuery() As DataTable
        'this function will get the hierarchie of metaqueries
        Dim _dataTable As New DataTable
        Dim sqlcmd As System.Data.SqlClient.SqlCommand = MetaQuery.GetSPCmdByMetaName("SSPMetaQueryChildDisplay")
        Dim reader As SqlDataReader = Nothing

        sqlcmd.Parameters("@QueryName").Value = QueryName
        reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection)
        _dataTable.BeginInit()
        _dataTable.BeginLoadData()
        _dataTable.Load(reader)
        _dataTable.EndLoadData()
        _dataTable.EndInit()
        reader.Close()
        sqlcmd.Dispose()
        reader = Nothing
        sqlcmd = Nothing
        Return _dataTable

    End Function

    ''' <summary>
    ''' Get the Metacolumns associate to the Metaquery
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub FillMetaColumns()

        Dim command As SqlCommand = CommonExt.Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Try
            If Me.QueryName <> String.Empty Then
                command.CommandText = "ssp_PrepareGrid"
                command.CommandType = CommandType.StoredProcedure
                command.Parameters.AddWithValue("@QueryName", QueryName)
                command.Parameters.AddWithValue("@UserID_FK", Base.AppManager.UserID)
                command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.ApplicationOption.LanguageId)
                command.Parameters.AddWithValue("@ColumnGroupID_FK", Base.IdRepository.METALIST_METACOLUMNGROUPE_VALUE)

                reader = command.ExecuteReader(CommandBehavior.CloseConnection)
                Me._metaColumns.Clear()
                Me._metaColumns.BeginLoadData()
                Me._metaColumns.Load(reader)
                Me._metaColumns.EndLoadData()
            Else
                Throw New Exception("QueryName is empty: MetaQuery.FillMetaColumns()")
            End If
        Catch ex As Exception
            Throw ex
        Finally
            reader.Close()
            reader = Nothing
            If command IsNot Nothing Then
                command.Dispose()
                command = Nothing
            End If
        End Try
    End Sub
    ''' <summary>
    '''  Get the Parameter use gor the metaquery
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub FillMetaParams()
        Dim command As SqlCommand = CommonExt.Base.Connection.Command
        Dim reader As SqlDataReader = Nothing
        Try
            If Me.QueryName <> String.Empty Then
                command.CommandText = "ssp_PrepareGrid"
                command.CommandType = CommandType.StoredProcedure
                command.Parameters.AddWithValue("@QueryName", QueryName)
                command.Parameters.AddWithValue("@UserID_FK", Base.AppManager.UserID)
                command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.ApplicationOption.LanguageId)
                command.Parameters.AddWithValue("@ColumnGroupID_FK", Base.IdRepository.METALIST_METACOLUMNGROUPE_PARAMETER)

                reader = command.ExecuteReader(CommandBehavior.CloseConnection)
                Me._metaParams.Clear()
                Me._metaParams.BeginLoadData()
                Me._metaParams.Load(reader)
                Me._metaParams.EndLoadData()
            Else
                Throw New Exception("QueryName is empty: MetaQuery.FillMetaParams()")
            End If
        Catch ex As Exception
            Throw ex
        Finally
            reader.Close()
            reader = Nothing
            If command IsNot Nothing Then
                command.Dispose()
                command = Nothing
            End If
        End Try
    End Sub

    ''' <summary>
    ''' Get Metacolumns LOV's
    ''' And Metacolumns Translates
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub GetLOV_LKP()
        Dim colVisible As Boolean
        Dim colName As String
        For Each row As DataRow In Me.MetaColumns.Rows
            colVisible = CBool(IIf(CInt(row("pVisible")) = 0, False, True))
            colName = row("ColumnName").ToString()
            '
            If Not row.IsNull("TranslateQueryID_FK") Then
                Dim gid As Guid = New Guid(row("TranslateQueryID_FK").ToString)
                Me.AddToListOfLookup(colName, gid)
                If colVisible Then
                    If Not _listOfVisibleLookup.ContainsKey(colName) Then ' Exception occur, if add twice the same key, because it's a sorted type
                        Me._listOfVisibleLookup.Add(colName, gid)
                    End If
                End If
                'Here we check for LOV when No TR/Lookup are available - 2012-11-07
            ElseIf Not row.IsNull("LOVQueryID_FK") Then
                Dim gid As Guid = New Guid(row("LOVQueryID_FK").ToString)
                Me.AddToListOfLookup(colName, gid)
                If colVisible Then
                    If Not _listOfVisibleLookup.ContainsKey(colName) Then ' Exception occur, if add twice the same key, because it's a sorted type
                        Me._listOfVisibleLookup.Add(colName, gid)
                    End If
                End If
            End If
            '
            If Not row.IsNull("LOVQueryID_FK") Then
                Dim gid As Guid = New Guid(row("LOVQueryID_FK").ToString)
                Me.AddToListOfLov(colName, gid)
                If colVisible Then
                    If Not _listOfVisibleLov.ContainsKey(colName) Then ' Exception occur, if add twice the same key, because it's a sorted type
                        Me._listOfVisibleLov.Add(colName, gid)
                    End If
                End If
            End If

        Next
    End Sub

    ''' <summary>
    ''' Get Metacolumns Params LOV's
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub GetParamsLOV_LKP()
        Dim colVisible As Boolean
        Dim colName As String
        For Each row As DataRow In Me.MetaParams.Rows
            colVisible = CBool(IIf(CInt(row("pVisible")) = 0, False, True))
            colName = row("ColumnName").ToString()
            '
            If Not row.IsNull("TranslateQueryID_FK") Then
                Dim gid As Guid = New Guid(row("TranslateQueryID_FK").ToString)
                Me.AddToListOfLookup(colName, gid)
                If colVisible Then
                    If Not _listOfVisibleLookup.ContainsKey(colName) Then ' Exception occur, if add twice the same key, because it's a sorted type
                        Me._listOfVisibleLookup.Add(colName, gid)
                    End If
                End If
            ElseIf Not row.IsNull("LOVQueryID_FK") Then
                Dim gid As Guid = New Guid(row("LOVQueryID_FK").ToString)
                Me.AddToListOfLookup(colName, gid)
                If colVisible Then
                    If Not _listOfVisibleLookup.ContainsKey(colName) Then ' Exception occur, if add twice the same key, because it's a sorted type
                        Me._listOfVisibleLookup.Add(colName, gid)
                    End If
                End If
            End If
            '
            If Not row.IsNull("LOVQueryID_FK") Then
                Dim gid As Guid = New Guid(row("LOVQueryID_FK").ToString)
                Me.AddToListOfLov(colName, gid)
                If colVisible Then
                    If Not _listOfVisibleLov.ContainsKey(colName) Then ' Exception occur, if add twice the same key, because it's a sorted type
                        Me._listOfVisibleLov.Add(colName, gid)
                    End If
                End If
            End If

        Next
    End Sub
    ''' <summary>
    ''' Populate our list of lookup to be use by the consumer
    ''' </summary>
    ''' <param name="keyColumn"></param>
    ''' <param name="qryID"></param>
    ''' <remarks></remarks>
    Public Sub AddToListOfLookup(ByVal keyColumn As String, ByVal qryID As Guid)
        If Not Me._listOfLookup.ContainsKey(keyColumn) Then ' Exception occur, if add twice the same key, because it's a sorted type
            Me._listOfLookup.Add(keyColumn, qryID)
        End If
    End Sub
    ''' <summary>
    ''' Populate our list of LOV to be use by the consumer
    ''' </summary>
    ''' <param name="keyColumn"></param>
    ''' <param name="qryID"></param>
    ''' <remarks></remarks>
    Public Sub AddToListOfLov(ByVal keyColumn As String, ByVal qryID As Guid)
        If Not Me._listOfLov.ContainsKey(keyColumn) Then ' Exception occur, if add twice the same key
            Me._listOfLov.Add(keyColumn, qryID)
        End If
    End Sub

    ''' <summary>
    ''' Convenient for debuging purpose
    ''' </summary>
    ''' <returns>QueryName is return</returns>
    ''' <remarks>Instead of the type, we will see the QueryName in Watch Window</remarks>
    Public Overrides Function ToString() As String
        Return QueryName
    End Function
#End Region
#Region " IDisposable Support "
    ' IDisposable
    Private disposedValue As Boolean = False        ' To detect redundant calls
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: free other state (managed objects).
                Me.ResultQuery.Dispose()
                Me.ResultQuery = Nothing
                Me._childQueries = Nothing
                Me.DefaultParentValue = Nothing
                Me.metaCUDCommand = Nothing
                Me._metaColumnCaption = Nothing
                Me._metaColumns = Nothing
                Me._listOfLookup = Nothing
                Me._listOfLov = Nothing
                Me._listOfVisibleLookup = Nothing
                Me._listOfVisibleLov = Nothing
            End If
            ' TODO: free your own state (unmanaged objects).
            ' TODO: set large fields to null.
        End If
        Me.disposedValue = True
    End Sub

    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

    Private Sub MetaQuery_BeforeSql(ByVal mq As MetaQuery, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.BeforeSql

    End Sub
End Class

